package com.starsoft.smdc.crawler.ths;

import java.io.InputStream;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.starsoft.frame.fileimport.ExcelReader;
import com.starsoft.frame.fileimport.pojo.Column;
import com.starsoft.frame.fileimport.pojo.DataTable;
import com.starsoft.frame.fileimport.pojo.NullType;
import com.starsoft.frame.fileimport.pojo.Table;
import com.starsoft.frame.fileimport.pojo.Table.TitleType;
import com.starsoft.frame.fileimport.pojo.ValueType;
import com.starsoft.frame.util.MapUtil;
import com.starsoft.frame.util.StringUtil;
import com.starsoft.smdc.bean.SmdcEr;
import com.starsoft.smdc.bean.SmdcErId;
import com.starsoft.smdc.bean.SmdcSecurity;
import com.starsoft.smdc.crawler.common.ErCrawler;
import com.starsoft.smdc.dao.ErDao;
import com.starsoft.smdc.dao.FundamentalDao;
import com.starsoft.smdc.util.SecurityType;

public class ErThs extends ThsService implements ErCrawler {

	private static Logger logger = LoggerFactory.getLogger(ErThs.class);

	@Autowired
	ErDao erDao;
	
	@Autowired
	FundamentalDao fundamentalDao;
	
	@Override
	public List<SmdcEr> update(SmdcSecurity security, Date beginDate) {
		if(!SecurityType.isStock(security.getSecType())){
			throw new RuntimeException("not stock, no er");
		}
		if(!checkBeginDate(beginDate)){
			return new ArrayList<SmdcEr>();
		}
		List<SmdcEr> result = new ArrayList<SmdcEr>();

		List<SmdcEr> erList = getBasicMain(security, beginDate);
		erDao.saveOrUpdate(erList);
		result.addAll(erList);
		
		erList=getBasicDebt(security, beginDate);
		erDao.saveOrUpdate(erList);
		result.addAll(erList);
		
		if ("银行".equals(security.getIndustryName2())) {
			erList.addAll(getBasicBank(security, beginDate));
			erDao.saveOrUpdate(erList);
			result.addAll(erList);
		}
		return result;
	}
	
	private boolean checkBeginDate(Date beginDate) {
		ZonedDateTime zonedBegin = ZonedDateTime.ofInstant(beginDate.toInstant(), ZoneId.systemDefault());
		ZonedDateTime zonedNow = ZonedDateTime.now();
		int beginQ = (zonedBegin.getMonthValue() - 1) / 3 + zonedBegin.getYear() * 4;
		int nowQ = (zonedNow.getMonthValue() - 1) / 3 + zonedNow.getYear() * 4;

		if (beginQ >= nowQ) {
			return false;
		} else {
			return true;
		}
	}

	private List<SmdcEr> getBasicDebt(SmdcSecurity security, Date beginDate){
		String apiName = "basicDebt";
		InputStream response = downLoad(apiName, security.getTicker());
		
		List<Column> columnList = new ArrayList<Column>();
		columnList.add(new Column("科目\\时间", "reportDate", ValueType.Date, NullType.notnull, "yyyy-MM-dd"));
		columnList.add(new Column("实收资本（或股本）(元)", "shares", ValueType.String, NullType.nullable));

		ExcelReader reader = new ExcelReader(ExcelReader.EXCEL2003, true);
		Table table = new Table(TitleType.OnlyCode, columnList);
		table.setSheetIndex(0);
		DataTable dataTable = reader.read(response, table);
		List<SmdcEr> erList = new ArrayList<SmdcEr>();
		for (Map<String, Object> mapObject : dataTable.getData()) {
			Date reportDate = (Date) mapObject.get("reportDate");
			if (reportDate.after(beginDate)) {
				SmdcErId id = new SmdcErId(security.getSecId(), reportDate);
				SmdcEr er = erDao.get(id);
				if (er == null) {
					er = new SmdcEr(id);
				} else if (!erDao.checkCanUpdate(er)) {
					continue;
				}
				convertToNumber(mapObject,"shares");
				MapUtil.updateBean(er, mapObject);
				erList.add(er);
			}
		}
		return erList;
	}
	
	private List<SmdcEr> getBasicMain(SmdcSecurity security, Date beginDate){
		String apiName = "basicMain";
		InputStream response = downLoad(apiName, security.getTicker());
		
		List<Column> columnList = new ArrayList<Column>();
		columnList.add(new Column("科目\\时间", "reportDate", ValueType.Date, NullType.notnull, "yyyy-MM-dd"));
		columnList.add(new Column("基本每股收益", "shareEarning", ValueType.String, NullType.nullable));
		columnList.add(new Column("净利润(元)", "totalEarning", ValueType.String, NullType.nullable));
		columnList.add(new Column("扣非净利润(元)", "totalEarningPrime", ValueType.String, NullType.nullable));
		columnList.add(new Column("营业总收入(元)", "revenue", ValueType.String, NullType.nullable));
		columnList.add(new Column("每股净资产", "shareAssert", ValueType.String, NullType.nullable));
		columnList.add(new Column("净资产收益率", "roeReport", ValueType.String, NullType.nullable));
		Table table = new Table(TitleType.OnlyCode, columnList);
		
		ExcelReader reader = new ExcelReader(ExcelReader.EXCEL2003, true);
		DataTable dataTable = reader.read(response, table);
		List<SmdcEr> erList = new ArrayList<SmdcEr>();
		for (Map<String, Object> mapObject : dataTable.getData()) {
			Date reportDate = (Date) mapObject.get("reportDate");
			if (reportDate.after(beginDate)) {
				SmdcErId id = new SmdcErId(security.getSecId(), reportDate);
				SmdcEr er = erDao.get(id);
				if (er == null) {
					er = new SmdcEr(id);
				} else if (!erDao.checkCanUpdate(er)) {
					continue;
				}
				convertToNumber(mapObject,"shareEarning");
				convertToNumber(mapObject,"totalEarning");
				convertToNumber(mapObject,"totalEarningPrime");
				convertToNumber(mapObject,"revenue");
				convertToNumber(mapObject,"shareAssert");
				convertToNumber(mapObject,"roeReport");
				MapUtil.updateBean(er, mapObject);
				erList.add(er);
			}
		}
		return erList;
	}
	
	
	
	private List<SmdcEr> getBasicBank(SmdcSecurity security, Date beginDate){
		String apiName = "basicBank";
		InputStream response = downLoad(apiName, security.getTicker());
		
		List<Column> columnList = new ArrayList<Column>();
		columnList.add(new Column("科目\\时间", "reportDate", ValueType.Date, NullType.notnull, "yyyy-MM-dd"));
		columnList.add(new Column("拨备覆盖率", "bobeiRatio", ValueType.String, NullType.nullable));
		columnList.add(new Column("不良贷款(元)", "badLoan", ValueType.String, NullType.nullable));
		columnList.add(new Column("不良贷款率", "badLoanRatio", ValueType.String, NullType.nullable));
		
		ExcelReader reader = new ExcelReader(ExcelReader.EXCEL2003, true);
		Table table = new Table(TitleType.OnlyCode, columnList);
		table.setSheetIndex(0);
		DataTable dataTable = reader.read(response, table);
		List<SmdcEr> erList = new ArrayList<SmdcEr>();
		for (Map<String, Object> mapObject : dataTable.getData()) {
			Date reportDate = (Date) mapObject.get("reportDate");
			if (reportDate.after(beginDate)) {
				SmdcErId id = new SmdcErId(security.getSecId(), reportDate);
				SmdcEr er = erDao.get(id);
				if (er == null) {
					er = new SmdcEr(id);
				} else if (!erDao.checkCanUpdate(er)) {
					continue;
				}
				convertToNumber(mapObject, "bobeiRatio");
				convertToNumber(mapObject, "badLoan");
				convertToNumber(mapObject, "badLoanRatio");
				MapUtil.updateBean(er, mapObject);
				erList.add(er);
			}
		}
		return erList;
	}

	private void convertToNumber(Map<String, Object> mapObject, String key){
		if (mapObject.get(key) != null) {
			String valueStr = ((String)mapObject.get(key)).trim();
			if(StringUtil.isEmpty(valueStr)){
				mapObject.put(key, null);
				return;
			}
			try {
				double number = 0;
				if(valueStr.contains("%")){
					number = Double.parseDouble(valueStr.split("%")[0]);
					number = number/100;
				} else if(valueStr.contains("万")){
					number = Double.parseDouble(valueStr.split("万")[0]);
					number = number*10000;
				}  else if(valueStr.contains("亿")){
					number = Double.parseDouble(valueStr.split("亿")[0]);
					number = number*10000*10000;
				} else {
					number = Double.parseDouble(valueStr);
				}
				mapObject.put(key, number);
			} catch (Exception e) {
				mapObject.put(key, null);
				logger.warn("Failed to convert {} to number for {}", valueStr, key);
			}
		}
	}
	
	@Override
	public List<SmdcEr> update(InputStream is) {
		throw new RuntimeException("Not support");
	}

}
